#include "types.h"
#include "bgi.h"
#include "utils.h"

static FillStyle_t const PredefinedFillStyle[12] =
{
  {                      /* No Fill                       */
    {
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    }
  },
  {                      /* Solid Fill                    */
    {
      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
    }
  },
  {                      /* Line Fill                     */
    {
      0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00
    }
  },
  {                      /* Lt Slash Fill                 */
    {
      0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
    }
  },
  {                      /* Slash Fill                    */
    {
      0xE0, 0xC1, 0x83, 0x07, 0x0E, 0x1C, 0x38, 0x70
    }
  },
  {                      /* Backslash Fill                */
    {
      0xE0, 0x70, 0x38, 0x1C, 0x0E, 0x07, 0x83, 0xC1
    }
  },
  {                      /* Lt Backslash Fill             */
    {
      0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01
    }
  },
  {                      /* Hatch Fill                    */
    {
      0xFF, 0x88, 0x88, 0x88, 0xFF, 0x88, 0x88, 0x88
    }
  },
  {                      /* XHatch Fill                   */
    {
      0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81
    }
  },
  {                      /* Interleave Fill               */
    {
      0xCC, 0x33, 0xCC, 0x33, 0xCC, 0x33, 0xCC, 0x33
    }
  },
  {                      /* Wide Dot Fill                 */
    {
      0x80, 0x00, 0x08, 0x00, 0x80, 0x00, 0x08, 0x00
    }
  },
  {                      /* Close Dot Fill                */
    {
      0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00
    }
  }
};

static FillStyle_t FillStyle =
{
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

void setFillStyle(uint8_t pattern, FillStyle_t _far *userPattern)
{
  FillStyle = (pattern == 0xff) ? *userPattern : PredefinedFillStyle[pattern];
}

void PatBarLine(coord_t y, coord_t x1, coord_t x2)
{
  coord_t x;
  uint16_t mask = FillStyle.style[y % 8];
  mask |= mask << 8;
  mask = _rotl(mask, x1 % 8);
  for(x = x1; x <= x2; ++x)
  {
    mask = _rotl(mask, 1);
    PutPixel(x, y, getFillColor(mask & 1));
  }
}

void PatBar(coord_t x1, coord_t y1, coord_t x2, coord_t y2)
{
  coord_t x, y;
  if(x1 > x2)
    x = x1, x1 = x2, x2 = x;
  if(y1 > y2)
    y = y1, y1 = y2, y2 = y;
  for(y = y1; y <= y2; ++y)
    PatBarLine(y, x1, x2);
}

void Clear(void)
{
  coord_t x, y;
  color_t bkgr = getBkgrColor();
  for(y = 0; y <= status.yres; ++y)
    for(x = 0; x <= status.xres; ++x)
      PutPixel(x, y, bkgr);
}
